#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "processo.h"

#define quantum 7

void escalonardorCircular (pSimulado *cpu, estado *prontos, pSimulado *tabelaPcb ){
    int indice;
    cpu->tempoUsado++;
    printf("\n tempo usado %d",cpu->tempoUsado);
    if (cpu->tempoUsado >= quantum){

        prontos->executando = (prontos->executando + 1) % prontos->tamanho;

        
        indice = prontos->executando;
        trocaProcesso(cpu, &tabelaPcb, prontos, indice);
    }
   
}

void trocaProcesso (pSimulado *cpu, pSimulado *tabelaPcb, estado *prontos, int indice){
        
    tabelaPcb[cpu->idProcesso] = *cpu;
    printf ("\nindice %d", indice);
    printf("\nlista %d", prontos->lista[indice]);
    printf("\nTrocando processo");
    *cpu = tabelaPcb[prontos->lista[indice]];
    printf ("\n passou");
}

void carregaProcesso(char nomeArq[], pSimulado *processo, int *numeroProcessos, estado *prontos){

    FILE *pinit;
    arrayPrograma *vetorPrograma;
    int i;
    
	pinit = fopen(nomeArq, "r");
    fscanf (pinit, "%d", &processo->tamanho);
    
    vetorPrograma = (arrayPrograma *) malloc(processo->tamanho * sizeof(arrayPrograma));
    i = 0; 
	while (!feof(pinit)){
		fscanf (pinit, "%s", &vetorPrograma[i].letra);
		
		if (vetorPrograma[i].letra == 'E'){
			vetorPrograma[i].numero[0] = '!' ;
            break;
		}
		else {
			fscanf (pinit, "%s", vetorPrograma[i].numero);
		}
		i++; 
	}
	processo->contPrograma = 0;
	processo->registrador = 0;
	processo->finalizado = 0;
    processo->programa = vetorPrograma;
    processo->tempoUsado = 0;
    processo->idProcesso = *numeroProcessos;
    prontos->lista[prontos->executando] = 
}

void carregaCPU(pSimulado processoNovo,pSimulado *cpu, estado *prontos){
    *cpu = processoNovo;
    prontos->executando = processoNovo.idProcesso;
    
}

void executaInstrucao(pSimulado *cpu, pSimulado *tabelaPcb, int *contTabela, int *numeroProcessos){
	char instrucao;
	int num;
	char arq[50];
    

	instrucao = cpu->programa[cpu->contPrograma].letra;
    printf("\n letra %c",instrucao);
     printf("\n file = %s ", cpu->programa[cpu->contPrograma].numero);
	switch (instrucao)
        {
			case 'S':{
				num = (int)atoi(cpu->programa[cpu->contPrograma].numero);
				cpu->registrador = num;
				break;
			   }
			case 'A':{
				num = (int)atoi(cpu->programa[cpu->contPrograma].numero);
				cpu->registrador = (cpu->registrador + num);
				break;
			   }
			case 'D':{
				num = (int)atoi(cpu->programa[cpu->contPrograma].numero);
				cpu->registrador = (cpu->registrador - num);
				break;
			   }
			case 'F':{
                *numeroProcessos++;
            	num = (int)atoi(cpu->programa[cpu->contPrograma].numero);
                
            	cpu->contPrograma++;
            	tabelaPcb[*contTabela] = *cpu;
				cpu->contPrograma = ((cpu->contPrograma + num)-1);
            	contTabela++;
				tabelaPcb[*contTabela].idProcesso = *contTabela;	
				break;
			   }
			case 'R':{
				*arq = cpu->programa[cpu->contPrograma].numero;
				carregaProcesso(arq, &tabelaPcb[cpu->idProcesso], *numeroProcessos);	
				break; 
			   }
	    }
	 cpu->contPrograma++;
     
}

int main(int argc, char** argv) {
    char pipe[0];
    int aux = 1, i;
	pSimulado init;
	pSimulado cpu;
	pSimulado *tabelaPcb;
    estado prontos;
	int contTabela = 0;
    int numeroProcessos = 0;
	
	tabelaPcb = (pSimulado *) malloc(100 * sizeof(pSimulado));
    
    /*Inicia o processo Init*/  
	carregaProcesso("init", &init, &numeroProcessos);
	/*coloca o processo Init na CPU*/
	carregaCPU(init,&cpu, &prontos);
	
	/*inclui processo na tabelaPcb*/ 
	tabelaPcb[contTabela] = init;
	init.idProcesso = contTabela;
	contTabela++;
	
	i = 0;

/*	while (i < init.tamanho){
		printf ("%c ", cpu.programa[i].letra);
		printf ("%s\n", cpu.programa[i].numero);
	//	printf("i = %d \n", i);
		i++; 
		
	}
 */
	while (aux == 1){
        scanf("%c",&pipe[0]);
		switch (pipe[0])
        {
           case 'q':
              printf("\nFim de uma unidade de tempo");
              executaInstrucao(&cpu, tabelaPcb, &contTabela, &numeroProcessos);
              printf ("\nregistrador = %d ", cpu.registrador);
              break;

            case 'u':
             printf("\nDesbloqueie o primeiro processo simulado que está na fila de bloqueados.");
             break;

           case'p':
             printf("\nImprima o estado atual do sistema.");
             break;
  
            case 't':{
             printf("\nFIM\n");
             aux = 2;
             break;
			}
             
           default:
             printf("\nFALHA!!!!!!!!\n");
             break; 
        }
                printf ("\nprontos %d", prontos.executando);
        escalonardorCircular (&cpu, &prontos, &tabelaPcb);
        aux = 1;
        printf("\n aux %d\n",aux);
	}
    
    return (EXIT_SUCCESS);
}
